package com.okilo.online.app.request

import android.os.Handler
import android.os.Looper
import com.okilo.online.app.OkiloApplication
import com.okilo.online.app.configs.OkiloConfigs
import com.okilo.online.app.configs.OkiloConfigs.addParams
import com.okilo.online.app.event.OkiloEventData
import com.okilo.online.app.event.room.OkiloPointManager
import com.okilo.online.app.tools.aes.OkiloAesUtil
import com.okilo.online.app.tools.log.JsonFormat
import com.okilo.online.app.tools.log.OkiloLog
import okio.IOException
import org.json.JSONObject

/**
 * 集成网络错误管理和重试功能
 */
class EnhancedHttpLoader: IHttpLoader {

    private val mainHandler = Handler(Looper.getMainLooper())

    /**
     * POST 请求（集成网络管理）
     */
    override fun post(url: String, params: JSONObject, callback: IHttpCallback) {
        //未登录，不添加公告参数
        if (OkiloConfigs.gOkiloLoginToken().isNotEmpty()){
            // 统一添加通用参数
            params.addParams()
        }
        val aesParams = OkiloAesUtil.encryptDefault(params.toString())

        OkiloLog.i("HttpUrl：  $url")
        OkiloLog.i("HttpParams： $params")
        OkiloLog.i("HttpParams AES：  $aesParams")

        val headers = HashMap<String, String>().apply {
            put("appid", OkiloConfigs.OKILO_APPNAME)
            put("product", OkiloConfigs.OKILO_APPNAME)
        }

        // 创建重试请求对象
        val retryRequest = NetworkManager.RetryRequest(
            requestType = "POST",
            url = url,
            params = params, // 保存原始参数，用于重试时重新加密
            originalCallback = callback
        )

        // 执行实际请求
        executePostRequest(url, aesParams, headers, retryRequest, callback)
    }

    /**
     * 文件上传（集成网络管理）
     */
    override fun upload(filePath: String, callback: IHttpCallback) {
        if (filePath.isEmpty()) {
            return
        }

        val headers = HashMap<String, String>().apply {
            put("appid", OkiloConfigs.OKILO_APPNAME)
            put("product", OkiloConfigs.OKILO_APPNAME)
        }

        val httpUrl = OkiloConfigs.gOkiloUploadFileUrl()

        // 创建重试请求对象
        val retryRequest = NetworkManager.RetryRequest(
            requestType = "UPLOAD",
            url = httpUrl,
            params = filePath, // 保存文件路径
            originalCallback = callback
        )

        // 执行实际上传
        executeUploadRequest(httpUrl, filePath, headers, retryRequest, callback)
    }

    /**
     * 执行实际的 POST 请求
     */
    private fun executePostRequest(url: String, encryptedParams: String, headers: Map<String, String>, retryRequest: NetworkManager.RetryRequest, callback: IHttpCallback) {
        OkHttpUtil.getInstance().postJson(url, encryptedParams, headers, object : OkHttpUtil.HttpCallback {
            override fun onSuccess(response: String) {
                handleRequestSuccess(response, url, retryRequest, callback, "POST")
            }

            override fun onFailure(e: IOException) {
                handleRequestFailure(e, url, retryRequest, callback, "POST")
            }
        })
    }

    /**
     * 执行实际上传请求
     */
    private fun executeUploadRequest(url: String, filePath: String, headers: Map<String, String>, retryRequest: NetworkManager.RetryRequest, callback: IHttpCallback) {
        OkHttpUtil.getInstance().uploadFile(url, "image", filePath, null, headers, object : OkHttpUtil.HttpCallback {
            override fun onSuccess(response: String) {
                handleRequestSuccess(response, url, retryRequest, callback, "UPLOAD")
            }

            override fun onFailure(e: IOException) {
                handleRequestFailure(e, url, retryRequest, callback, "UPLOAD")
            }
        })
    }

    /**
     * 统一处理请求成功
     */
    private fun handleRequestSuccess(response: String, url: String, retryRequest: NetworkManager.RetryRequest, callback: IHttpCallback, requestType: String) {
        mainHandler.post {
            callback.onRequestFinish()
        }

        response.let {
            // 记录日志
            logSuccess(url, retryRequest.params, it, requestType)

            // 处理响应数据
            processResponseData(it, callback, requestType)
        }
    }

    /**
     * 统一处理请求失败
     */
    private fun handleRequestFailure(e: IOException, url: String, retryRequest: NetworkManager.RetryRequest, callback: IHttpCallback, requestType: String) {
        OkiloApplication.app.publisher.publish(OkiloEventData(OkiloEventData.TYPE.OKILO_HTTP_REQUEST_ERROR))
        val errorCode = mapExceptionToErrorCode(e)
        val errorMsg = e.message ?: "${if (requestType == "POST") "Network" else "Upload"} request failed"

        // 记录错误日志
        logFailure(url, retryRequest.params, e.message ?: "Unknown error", requestType)

        // 交给网络管理器处理
        NetworkManager.handleNetworkError(errorCode, errorMsg, retryRequest)

        // 回调给原始回调
        notifyRequestError(errorCode, errorMsg, callback)
    }

    /**
     * 记录成功日志
     */
    private fun logSuccess(url: String, params: Any?, response: String, requestType: String) {
        Thread {
            when (requestType) {
                "POST" -> {
                    val path = (params as? JSONObject)?.optString("path") ?: ""
                    val result = OkiloAesUtil.decryptDefault(response)
                    OkiloLog.i(
                        "\nurl: $url \n" +
                                "path: $path \n" +
                                "response: ${JsonFormat.format(result)}"
                    )
                }
                "UPLOAD" -> {
                    val filePath = params as? String ?: ""
                    OkiloLog.i(
                        "\nurl: $url \n" +
                                "imgPath: $filePath \n" +
                                "response: ${JsonFormat.format(response)}"
                    )
                }
            }
        }.start()
    }

    /**
     * 记录失败日志
     */
    private fun logFailure(url: String, params: Any?, error: String, requestType: String) {
        when (requestType) {
            "POST" -> {
                val path = (params as? JSONObject)?.optString("path") ?: ""
                OkiloLog.e(
                    "\nurl: $url \n" +
                            "path: $path \n" +
                            "error: $error"
                )
            }
            "UPLOAD" -> {
                val filePath = params as? String ?: ""
                OkiloLog.e(
                    "\nurl: $url \n" +
                            "imgPath: $filePath \n" +
                            "error: $error"
                )
            }
        }
    }

    /**
     * 处理响应数据
     */
    private fun processResponseData(response: String, callback: IHttpCallback, requestType: String) {
        try {
            // 解密响应数据（POST请求需要解密，UPLOAD可能不需要）
            val result = if (requestType == "POST") {
                OkiloAesUtil.decryptDefault(response)
            } else {
                response
            }

            val data = JSONObject(result)
            when (val code = data.optInt("code")) {
                0 -> {
                    mainHandler.post {
                        callback.onRequestSuccess(data)
                    }
                }
                else -> {
                    // 业务错误，不进行网络重试
                    val errorObj = JSONObject().apply {
                        put("errorCode", code)
                        put("errorMsg", data.optString("msg"))
                    }
                    mainHandler.post {
                        callback.onRequestError(errorObj)
                    }
                }
            }
        } catch (e: Exception) {
            // 数据处理异常
            val errorObj = JSONObject().apply {
                put("errorCode", HttpErrorCode.PROCESS_ERROR)
                put("errorMsg", "Data processing error: ${e.message}")
            }
            mainHandler.post {
                callback.onRequestError(errorObj)
            }
        }
    }

    /**
     * 通知请求错误
     */
    private fun notifyRequestError(
        errorCode: Int,
        errorMsg: String,
        callback: IHttpCallback
    ) {
        val errorObj = JSONObject().apply {
            put("errorCode", errorCode)
            put("errorMsg", errorMsg)
        }
        mainHandler.post {
            callback.onRequestError(errorObj)
            callback.onRequestFinish()
        }
    }

    /**
     * 将异常映射为错误码
     */
    private fun mapExceptionToErrorCode(e: IOException): Int {
        return when (e) {
            is java.net.SocketTimeoutException -> HttpErrorCode.TIMEOUT_ERROR
            is java.net.UnknownHostException -> HttpErrorCode.NETWORK_UNAVAILABLE
            is java.net.ConnectException -> HttpErrorCode.NETWORK_UNAVAILABLE
            is java.net.SocketException -> HttpErrorCode.NETWORK_UNAVAILABLE
            else -> HttpErrorCode.UNKNOWN_ERROR
        }
    }

    /**
     * 添加打点事件
     */
    override fun addPoint(eventName: String, remark: String?) {
        OkiloLog.i(">>>>>>>>>>>>>>eventName：$eventName，remark：$remark")
        val eventType = eventName.uppercase()
        if (remark != null) {
            OkiloPointManager.getInstance().track(eventType, remark)
        } else {
            OkiloPointManager.getInstance().track(eventType, "")
        }
    }

    /**
     * 设置请求tag
     */
    override fun setTag(tag: Any) {
        // 可以在这里扩展，将tag与网络管理器关联
    }

    /**
     * 取消请求
     */
    override fun cancelTag(tag: Any) {
        // 可以在这里扩展，取消网络管理器中的相关请求
    }

    /**
     * 扩展方法：手动触发重试
     */
    fun triggerManualRetry() {
        NetworkManager.triggerRetry()
    }

    /**
     * 扩展方法：清空重试队列
     */
    fun clearRetryQueue() {
        NetworkManager.resetState()
    }
}